/*
 * @Author: kevin.huang 
 * @Date: 2018-07-21 19:48:42 
 * @Last Modified by: kevin.huang
 * @Last Modified time: 2019-05-08 20:39:10
 * Copyright (c): kevin.huang Released under MIT License
 */
(function (global, factory) {
    if (typeof define === 'function' && define.amd && !window["_all_in_"]) {
        define(['$B'], function (_$B) {
            return factory(global, _$B);
        });
    } else {
        if (!global["$B"]) {
            global["$B"] = {};
        }
        factory(global, global["$B"]);
    }
}(typeof window !== "undefined" ? window : this, function (window, $B) {
    function getDateDiff(sTime, eTime) {
        return parseInt((eTime.getTime() - sTime.getTime()));
    }
    var $body;
    function _getBody() {
        if (!$body) {
            $body = $(window.document.body).css("position", "relative");
        }
        return $body;
    }
    var uploadIconHtml = '<i class="fa fa-up-small" style="color:#fff;padding-right:4px;"></i>';
    var formTag = '<form enctype="multipart/form-data"   method="post" name="k_fileUpload_from"></form>';
    /**
	 * 利用iframe模拟ajax实现多附件上传
	 * args={
		  	target:$("#div"),
		  	timeout:180, //超时时间 秒
            url:contextPath+'/bdms/menu/upload.do',
            isCross : 是否是跨域上传
            crossHelperPage: 跨域上传时候需要设置一个辅助页面,被跨域放将结果存放在crossHelperPage.Window.name
		  	// 待上传的文件列表，用于设置input的 name 以在服务器区分文件  	
			files:[{name:'xmlfile',type:'.xml',label:'提示标题',must:'是否必须上传文件'},{name:'xlsfile',type:'.xls,.xlsx',label:'提示标题'}], 
			onselected:fn(value,id,accept){ return true / false } ,//选择文件后的事件请返回true 以便通过验证
			immediate:true, //选择文件后是否立即自动上传，即不用用户点击提交按钮就上传
			success:function(res){}, //成功时候的回调
			ondeleted:function(res){ //删除回调},
			setParams:function(return {p1:111}), //设置参数
			error:fn(res), //错误回调
			reposition:fn //重设位置
	 * }
	 ****/
    function MutilUpload(args) {
        $B.extend(this, MutilUpload);
        this.target = args.target.addClass("k_mutilupload_wrap");
        this.target.children().remove();
        this.onselected = args.onselected;
        this.immediate = args.immediate;
        this.success = args.success;
        this.ondeleted = args.ondeleted;
        this.isCross = args.isCross;
        this.crossHelperPage = args.crossHelperPage;
        this.error = args.error;
        this.setParams = args.setParams;
        this.url = args.url;
        this.form = $(formTag).appendTo(this.target);
        this.timeout = (args.timeout ? args.timeout : 300) * 1000;
        this.uploading = false;
        this.init = typeof args.init === 'undefined' ? true : args.init;
        if (this.init && $.isArray(args.files)) {
            for (var i = 0, len = args.files.length; i < len; ++i) {
                this._createFileInput(args.files[i]);
                if (i < len - 1) {
                    this.form.append("<br/>");
                }
            }
        }
    }
    MutilUpload.prototype = {
        _createIframe: function (uploadFileArray) {
            var id = "_ifr_" + $B.generateMixed(8);
            var _this = this;
            _this.isIniting = true;
            var ifr = $('<iframe  name="' + id + '" id="' + id + '" style="display:none;"></iframe>').appendTo(_getBody());
            setTimeout(function () {
                _this.isIniting = false;
            }, 10);
            var crossHelperPage = _this.crossHelperPage;
            var isCross = _this.isCross;
            if (isCross) {
                if (!crossHelperPage) {
                    var links = $("head").children("link");
                    if (links.length === 1) {
                        crossHelperPage = links.first().attr("href");
                    } else {
                        crossHelperPage = links.eq(2).attr("href");
                    }
                }
            }
            ifr.on("load", function (e) {
                if (_this.isIniting) {
                    return;
                }
                clearInterval(ifr.data("timeoutchker"));
                _this.uploading = false;
                var i = 0,
                    len = uploadFileArray.length;
                var callBakFn,
                    message,
                    json,
                    res,
                    isSuccess = true;
                if (isCross) {//跨域
                    if (!ifr.attr("src")) {
                        try {
                            ifr[0].src = crossHelperPage;
                        } catch (ex1) {
                        }
                        return;
                    } else {
                        try {
                            ifr.removeAttr("src");
                            res = ifr[0].contentWindow.name;
                            json = eval("(" + res + ")");
                        } catch (e1) {
                            isSuccess = false;
                            message = $B.config.uploadFail;
                            callBakFn = _this.error;
                        }
                    }
                } else {
                    try {
                        var ifrDoc = ifr[0].contentWindow.document || ifr[0].contentDocument;
                        var body = $(ifrDoc.body);
                        // body.children().remove();
                        res = body.text();
                        json = eval("(" + res + ")");
                    } catch (e1) {
                        isSuccess = false;
                        message = $B.config.uploadFail;
                        callBakFn = _this.error;
                        console.log("to json err " + res);
                        console.log(e1);
                    }
                }
                if (json) {
                    if (json.code !== 0) {
                        isSuccess = false;
                        callBakFn = _this.error;
                        message = $B.config.uploadFail;
                        if (json.message && json.message !== "") {
                            message = json.message;
                        }
                    } else {
                        callBakFn = _this.success;
                    }
                }
                while (i < len) {
                    var vInput = uploadFileArray[i];
                    var $a = vInput.next().removeClass("k_update_close_disable");
                    if (isSuccess) {
                        vInput.html(uploadIconHtml + vInput.attr("title"));
                        $a.children("i").attr("class", "fa fa-check-1");
                    } else {
                        vInput.html(uploadIconHtml + message);
                    }
                    i++;
                }
                if (typeof callBakFn === "function") {
                    callBakFn.call(uploadFileArray, json);
                }
                ifr.remove();
                uploadFileArray = undefined;
            });
            return {
                id: id,
                ifr: ifr
            };
        },
        _changeFn: function (e) {
            var _this = e.data._this;
            var input = $(this);
            var v = input.val();
            var vInput = input.next("div");
            var accept = input.attr("accept").toLowerCase();
            vInput.next("a").children("i").attr("class", "fa fa-cancel-2").attr("_class", "fa fa-cancel-2");
            var must = input.attr("must");
            var isGoon = true;
            if (must && v === "") {
                vInput.html(uploadIconHtml + must);
                return false;
            }
            var strFileName = v.replace(/^.+?\\([^\\]+?)(\.[^\.\\]*?)?$/gi, "$1$2");
            var srcFileName = strFileName;
            var label = input.attr("label");
            var name = input.attr("name");
            if (accept !== '.*') {
                var suffix = srcFileName.replace(/.+\./, "").toLowerCase();
                if (accept.indexOf(suffix) < 0) {
                    input.val("");
                    var acceptMsg = $B.config.uploadAccept.replace("<accept>", accept);
                    if ($B.alert) {
                        $B.alert({
                            width: 300,
                            height: 120,
                            message: acceptMsg,
                            timeout: 2
                        });
                        vInput.html(uploadIconHtml + label);
                    } else {
                        vInput.html(uploadIconHtml + acceptMsg);
                    }
                    return;
                }
            }
            if (strFileName === "") {
                strFileName = label;
            }
            if (typeof _this.onselected === 'function') {
                if (!_this.onselected.call(input, srcFileName, name, accept)) {
                    input.val("");
                    vInput.html(uploadIconHtml + label);
                    isGoon = false;
                }
            }
            if (isGoon) {
                vInput.attr("title", strFileName).html(uploadIconHtml + strFileName);
                if (_this.immediate) { //是否立即上传
                    var others = vInput.parent().siblings("div");
                    var othersInput = others.find("input[type=file]");
                    othersInput.hide().attr("disabled", "disabled");
                    _this.submit();
                    othersInput.show().removeAttr("disabled");
                }
            }
        },
        _createFileInput: function (file) {
            var must = file.must ? "must=" + file.must : "";
            var multiple = file.multiple ? 'multiple="multiple"' : "";
            var it = $('<div class="k_upload_file_item_wrap k_box_size" style="width:auto;max-width: 100%; "></div>').appendTo(this.form);
            var $input = $('<input  ' + multiple + ' ' + must + ' label="' + file.label + '" id="' + file.name + '" name="' + file.name + '" type="file" accept="' + file.type + '" style="width:100%;">').appendTo(it);
            var vinput = $('<div title="' + file.label + '" class="k_visual_file_item_input k_box_size">' + uploadIconHtml + file.label + '</div>').appendTo(it);
            this._bindFileEvents(vinput);
            var _this = this;
            var $a = $("<a class='k_upload_file_item_delete' title='" + $B.config.clearFile + "'><i class='fa fa-cancel-2'></i></a>").appendTo(it);
            $a.click(function () {
                var $t = $(this);
                if ($t.hasClass("k_update_close_disable")) {
                    return false;
                }
                var $vInput = $t.prev();
                var $input = $vInput.prev();
                var id = $input.attr("id");
                var label = $input.attr("label");
                var $itWrap = $t.parent();
                if ($itWrap.attr("d")) {
                    $B.confirm({
                        width: 280,
                        height: 125,
                        message: $B.config.uploadClearConfirm,
                        okText: $B.config.uploadClear,
                        noText: $B.config.uploadRemove,
                        noIcon: 'fa-trash',
                        okIcon: 'fa-cancel-circled',
                        okFn: function () {
                            if (typeof _this.ondeleted === "function" && $input.val() !== "") {
                                _this.ondeleted(id);
                            }
                            $vInput.html(uploadIconHtml + label).attr("title", label);
                            $input.val("");
                            $vInput.next("a").children("i").attr("class", "fa fa-cancel-2").attr("_class", "fa fa-cancel-2");
                        },
                        noFn: function () {
                            $itWrap.prev("br").remove();
                            $itWrap.remove();
                            if (typeof _this.ondeleted === "function") {
                                _this.ondeleted(id);
                            }
                        }
                    });
                } else {
                    if (typeof _this.ondeleted === "function" && $input.val() !== "") {
                        _this.ondeleted(id);
                    }
                    $vInput.html(uploadIconHtml + label).attr("title", label);
                    $input.val("");
                    $vInput.next("a").children("i").attr("class", "fa fa-cancel-2").attr("_class", "fa fa-cancel-2");
                }
            }).mouseover(function () {//
                var $t = $(this).children("i");
                var _class = $t.attr("class");
                $t.attr("class", "fa fa-cancel-2").attr("_class", _class);
            }).mouseout(function () {
                var $t = $(this).children("i");
                var _class = $t.attr("_class");
                $t.attr("class", _class);
            });
            return it;
        },
        _bindFileEvents: function (vinput) {
            var _this = this;
            vinput.on("click", function () {
                var $v = $(this);
                var $_iput = $v.prev("input");
                if ($v.siblings("a").hasClass("k_update_close_disable")) {
                    return false;
                }
                $_iput.unbind("change").val("").on("change", {
                    _this: _this
                }, _this._changeFn);
                $_iput.trigger("click");
            });
        },
        submit: function () {
            //不是立即上传，外部手动上传
            if (!this.immediate && this.uploading) {
                console.log("is uploading ，donot submit！");
                return;
            }
            this.uploading = true;
            clearTimeout(this.tipTimer);
            var uploadingArray = [];
            var emptyFiles = [];
            var go2submit = false;
            var fileNames = [];
            this.form.children(".k_upload_file_item_wrap").each(function () {
                var $it = $(this);
                var input = $it.children("input");
                if (input.attr("disabled")) {
                    return true;
                }
                var vInput = input.next();
                var a = vInput.next();
                if (input.val() === "" && input.attr("must")) {
                    vInput.html("<span style='color:#FFBCBF'>" + uploadIconHtml + $B.config.uploadNotEmpty + "</span>");
                    emptyFiles.push(vInput);
                } else {
                    vInput.html("<span style='color:#fff'><span style='padding-right:4px;'><i style='color:#fff' class='fa fa-spin3 animate-spin'></i></span>" + $B.config.uploading + "</span>");
                    a.addClass("k_update_close_disable");
                    uploadingArray.push(vInput);
                    go2submit = true;
                    fileNames.push(input.attr("id"));
                }
            });
            if (go2submit) {
                this.form.children("input[type=hidden]").remove();
                if (typeof this.setParams === "function") {
                    var prs = this.setParams.call(this, fileNames);
                    if ($.isPlainObject(prs)) {
                        var keys = Object.keys(prs),
                            key;
                        for (var i = 0, len = keys.length; i < len; ++i) {
                            key = keys[i];
                            this.form.append("<input type='hidden' name='" + key + "' id='" + key + "' value='" + prs[key] + "'/>");
                        }
                    }
                }
                var _this = this;
                var ret = this._createIframe(uploadingArray);
                _this.isIniting = false;
                var ifrId = ret.id;
                //避免缓存问题
                var url = this.url;
                if (url.indexOf("?") > 0) {
                    url = url + "&_t_=" + $B.generateMixed(5);
                } else {
                    url = url + "?_t_=" + $B.generateMixed(5);
                }
                this.form.attr("target", ifrId);
                this.form.attr("action", url);
                var startTime = new Date();
                this.form[0].submit();
                var ivt = setInterval(function () {
                    var endTime = new Date();
                    var diff = getDateDiff(startTime, endTime);
                    if (diff > _this.timeout) {
                        _this.uploading = false;
                        clearInterval(ret.ifr.data("timeoutchker"));
                        ret.ifr.remove();
                        ret = undefined;
                        for (var j = 0, jlen = uploadingArray.length; j < jlen; ++j) {
                            uploadingArray[j].html(uploadIconHtml + $B.config.uploadTimeout);
                            uploadingArray[j].siblings("a").removeClass("k_update_close_disable");
                        }
                    }
                }, 1500);
                ret.ifr.data("timeoutchker", ivt);
            } else {
                this.uploading = false;
            }
            this.tipTimer = setTimeout(function () {
                for (var i = 0, len = emptyFiles.length; i < len; ++i) {
                    emptyFiles[i].html(uploadIconHtml + emptyFiles[i].attr("title"));
                }
            }, 1000);
        },
        /***
         * file = {
                    name: 'xmlfile',
                    type: '.xml',
                    label: '请选择xml文件请选择xml文件请选择xml文件',
                    must: '必须上传文件!'
                }
         * **/
        addFile: function (file) {
            if (this.form.children(".k_upload_file_item_wrap").length > 0) {
                this.form.append("<br/>");
            }
            var it = this._createFileInput(file);
            it.attr("d", 1);
        },
        reset: function () {
            this.form.children(".k_upload_file_item_wrap").each(function () {
                var $it = $(this);
                var input = $it.children("input");
                input.val("");
                var label = input.attr("label");
                var vInput = $it.children("div");
                vInput.html(uploadIconHtml + label).attr("title", label);
                var $i = $it.children("a").removeClass("k_update_close_disable").children("i");
                $i.removeClass("fa-check-1").addClass("fa-cancel-2");
            });
        },
        hasFiles: function () {
            var res = false;
            this.form.children(".k_upload_file_item_wrap").each(function () {
                var $it = $(this);
                var input = $it.children("input");
                if (input.val() !== "") {
                    res = true;
                    return false;
                }
            });
            return res;
        }
    };

    $B["MutilUpload"] = MutilUpload;
    /***
    * xls导出封装
    * args = {
    *  target : 提示下载的容器
    *  url: 下载地址，
    *  fileName:'下载名称',
    *  mimeType:'文件类型',
    *  message:'提示语',
    *  ivtTime:'检测间距，毫秒',
    *  sheetName:'导出xls时候设置的sheet名称',
    *  params：{},附加的参数
    *  onSuccess:function(res){}
    *  model = {startRow :开始行好, file:模板文件名} //xls下载用
    * }
    * ***/
    $B.downLoad = function (args) {
        args.target.children().remove();
        var inteVal, ivtTime = 1500;
        if (args.ivtTime) {
            ivtTime = args.ivtTime;
        }
        var date = new Date();
        var finish_down_key = date.getDay() + '' + date.getHours() + '' + date.getMinutes() + '' + date.getSeconds() + '' + date.getMilliseconds() + $B.generateMixed(12);
        var _this = this;
        var ifrId = "k_" + $B.generateMixed(12);
        var $ifr = $('<iframe name="' + ifrId + '" id="' + ifrId + '" style="display: none"></iframe>').appendTo(args.target);
        var ifr = $ifr[0];
        var message = args.message ? args.message : "正在导出......";
        var _url = args.url;
        if (_url.indexOf("?") > 0) {
            _url = _url + "&isifr=1&_diff=" + $B.generateMixed(4);
        } else {
            _url = _url + "?isifr=1&_diff=" + $B.generateMixed(4);
        }
        var $msg = $("<h3 id='k_file_export_xls_msg_'  style='height:20px;line-height:20px;text-align:center;padding-top:12px;'><div class='loading' style='width:110px;margin:0px auto;'><i class='fa-spin3 animate-spin'></i><span style='padding-left:12px;'>" + message + "</span></div></h3>").appendTo(args.target);
        var $form = $('<form action="' + _url + '" target="' + ifrId + '" method="post" ></form>').appendTo(args.target);
        if (args.fileName) {
            $form.append('<input type="hidden" id="fileName" name="fileName" value="' + encodeURIComponent(args.fileName) + '"/>');
        }
        if (args.sheetName) {
            $form.append('<input type="hidden" id="sheetName" name="sheetName" value="' + encodeURIComponent(args.sheetName) + '"/>');
        }
        if (args.mimeType) {
            $form.append('<input type="hidden" id="mimeType" name="mimeType" value="' + encodeURIComponent(args.mimeType) + '"/>');
        }
        $form.append('<input type="hidden" id="k_finish_down_key_" name="k_finish_down_key_" value="' + finish_down_key + '"/>');
        var isModel = 0;
        if ($.isPlainObject(args.model)) {
            isModel = 1;
            $form.append('<input type="hidden" id="modelfile" name="modelfile" value="' + encodeURIComponent(args.model.file) + '"/>');
            $form.append('<input type="hidden" id="startrow" name="startrow" value="' + args.model.startRow + '"/>');
        }
        $form.append('<input type="hidden" id="ismodel" name="ismodel" value="' + isModel + '"/>');
        /******补充上额外的参数******/
        if ($.isPlainObject(args.params)) {
            Object.keys(args.params).forEach(function (p) {
                var v = args.params[p];
                $form.append('<input type="hidden" id="' + p + '" name="' + p + '" value="' + encodeURIComponent(v) + '"/>');
            });
        }
        var callReturn = typeof args.onSuccess === 'function';
        $ifr.on("load", function () {
            clearInterval(inteVal);
            try {
                var _$body = $(window.frames[ifrId].document.body);
                var res = _$body.text();
                if (res && res !== '') {
                    var json = eval("(" + res + ")");
                    $msg.html("<h2>" + json.message + "</h2>");
                    if (json.code === 0) {
                        if (callReturn) {
                            args.onSuccess(json);
                        }
                    }
                    return;
                }
            } catch (e) {
                $msg.html("<h2>" + $B.config.expException + "</h2>");
                console.log(e);
                return;
            }
        });
        $form[0].submit();
        var regex = /(\/\w+)/g;
        var match, lastChar;
        do {
            match = regex.exec(args.url);
            if (match !== null) {
                lastChar = match[0];
            }
        } while (match !== null);
        var url = args.url.replace(lastChar, "/checkresponse");
        if (url.indexOf("?") > 0) {
            url = url + '&k_finish_down_key_=' + finish_down_key;
        } else {
            url = url + '?k_finish_down_key_=' + finish_down_key;
        }
        inteVal = setInterval(function () {
            try {
                var prt = args.target.parent();
                while (prt.length > 0 && prt[0].tagName !== "BODY") {
                    prt = prt.parent();
                }
                if (prt[0].tagName !== "BODY") {
                    clearInterval(inteVal);
                    return;
                }
                var _$body = $(window.frames[ifrId].document.body);
                var res = _$body.text();
                if (res && res !== '') {
                    clearInterval(inteVal);
                    var json = eval("(" + res + ")");
                    $msg.html("<h2>" + json.message + "</h2>");
                    return;
                }
            } catch (e) {
                clearInterval(inteVal);
                $msg.html("<h2>" + $B.config.expException + "</h2>");
                console.log(e);
                return;
            }
            $B.request({
                url: url + "&_t=" + $B.generateMixed(5),
                ok: function (msg, data, res) {
                    if (msg !== 'null') {
                        clearInterval(inteVal);
                        $msg.html("<h2>" + msg + "</h2>");
                        if (callReturn) {
                            setTimeout(function () {
                                args.onSuccess(res);
                            }, 10);
                        }
                    }
                }
            });
        }, ivtTime);
    };
    return MutilUpload;
}));